Skip to content

feat(diff): compare call-graph edges in snapshot diff (closes #297) - #298

Merged
Wolfvin merged 2 commits into
mainfrom
feat/issue-297-edge-diff
Jul 17, 2026
Merged

feat(diff): compare call-graph edges in snapshot diff (closes #297)#298
Wolfvin merged 2 commits into
mainfrom
feat/issue-297-edge-diff

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Closes #297.

Masalah

Snapshot menyimpan 25.876 edge ke disk, tapi _diff_backend() hanya membandingkan nodes — kata edges tidak muncul sekali pun di fungsi itu. Perubahan struktural yang tidak menambah/menghapus fungsi tak terlihat sepenuhnya.

Yang berubah

_diff_backend() sekarang mengembalikan added_edges, removed_edges, added_edge_count, removed_edge_count, unresolved_edges; summary di diff_snapshots() + diff_current_vs_last() dapat edges_added / edges_removed.

Keputusan desain — spec asli issue SALAH, dikoreksi di sini

Issue menulis identitas edge = (from, to). Itu node id yang memuat nomor baris, jadi fungsi yang cuma bergeser baris melaporkan semua edge-nya hilang+muncul. Terbukti pada registry nyata 12.982 edge:

Skenario: geser baris seluruh codebase, 0 perubahan nyata added removed palsu
(from,to) id mentah (spec asli) 1.589 1.589 3.178
(file, impl_for, fn) (PR ini) 0 0 0

Pemilihan kunci diukur atas 2.429 node: (file,fn) → 38 tabrakan; (file, impl_for, fn)9 (0,37%), dan ke-9 nya sudah ditandai duplicate_define: true oleh CodeLens sendiri (closure visit/_walk yang memang didefinisikan berulang). Detail + bukti di komentar issue.

Lainnya: resolved-only (82% edge nyata = call stdlib append/strip/get, dihitung bukan dienumerasi — 10.512 unresolved saya cocok persis dengan type_resolution.edges_unresolved yang dilaporkan scanner sendiri); set bukan multiset; via_self kualifier; detail cap 100 + truncated, count eksak.

Verifikasi (dijalankan, bukan diklaim)

  • 16 test baru (tests/test_diff_engine_edges.py) — diff_engine.py sebelumnya nol coverage. Test geral-baris terbukti gagal kalau fix dicabut (dicek langsung).
  • Workspace polyglot nyata (smart-tax-assistance/app, 425 file, 191 Rust / 101 TSX / 127 C++): geser baris 3.878 dari 4.188 id → 0/0. Hapus 3 edge nyata → tepat 3 terdeteksi dengan nama + file benar.
  • CLI end-to-end: impact --check diffsummary memuat edges_added: 0, edges_removed: 2.
  • Full suite: 19 gagal di branch, 19 gagal di main, daftar identik — nol regresi. Ke-19 pre-existing (audit(ci): triage 13 test failures unmasked by segfault fix (#266) #271 Group B pagination + Windows-env).

Found, not fixed (Tier 2)

Command count tetap 12. Tidak ada engine/command baru → skip-design-doc.

🤖 Generated with Claude Code

Snapshots stored 25,876 edges on disk but _diff_backend() only ever
compared nodes, so any structural change that neither added nor removed
a function was invisible.

Edge identity is (file, impl_for, fn) per endpoint, not the raw node id.
Node ids embed a line number, so id-keyed edges reported every edge of a
function that merely shifted lines as removed and re-added: on the real
425-file polyglot workspace a whole-codebase line shift produced 3,178
false reports from zero real changes. Keying through the node map drops
that to 0 while still detecting genuine edge additions.

Resolved edges only. 82% of real edges are unresolved stdlib calls
(append, strip, get) and would drown the signal, so they are tallied
rather than enumerated. Pairs form a set: one edge is recorded per call
site, and call-site count is not graph shape. via_self is a qualifier
and stays out of identity.

Detail lists are capped at 100 with a truncated flag; counts stay exact.
Legacy node fields are untouched — commands/diff.py, dashboard,
formatters and MCP read them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

In an edge diff `from`/`to` already mean an edge's endpoints, so reusing
them for the old/new snapshot sides of the unresolved tally reads as a
bug at a glance. No consumers yet — renaming now is free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

💡 Need a hand with PR review? Try Gitar by Sonar!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(diff): compare call-graph edges in snapshot diff — 25,876 edges saved to disk but never compared

1 participant